package com.goldsprite.gsgengine.gsgdxf.screens;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputMultiplexer;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.badlogic.gdx.utils.viewport.Viewport;
import com.goldsprite.gsgengine.core.IGameLoop;
import com.goldsprite.gsgengine.core.managers.GameObjectManager;
import com.goldsprite.gsgengine.core.managers.Manager;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class SceneManager extends Manager implements IGameLoop {
	private static SceneManager instance;
	private final Map<Class<?>, Scene> scenes = new ConcurrentHashMap<>(); // 使用线程安全的集合
	private Scene currentScene;
	private Scene launchScene;
	private final InputMultiplexer inputMultiplexer = new InputMultiplexer();
	private Viewport viewport;

	public SceneManager() {
		if (instance != null) {
			throw new RuntimeException("非法创建实例，仅允许1个SceneManager实例存在");
		}
		instance = this;
		initViewport();
	}

	public static SceneManager getInstance() {
		if (instance == null) {
			throw new IllegalStateException("SceneManager尚未初始化");
		}
		return instance;
	}

	public void initViewport() {
		setViewport(640, 480);
	}

	public void setViewport(float worldWidth, float worldHeight) {
		this.viewport = new FitViewport(worldWidth, worldHeight);
	}

	public Viewport getViewport() {
		return viewport;
	}

	public SceneManager addScene(Scene scene) {
		Class<?> key = scene.getClass();
		if (!scenes.containsKey(key)) {
			scenes.put(key, scene);
			scene.setSceneManager(this);
			scene.setImp(new InputMultiplexer());
		}
		if (currentScene == null) {
			setCurrentScene(scene);
		}
		return this;
	}

	public Scene getScene(Class<?> key) {
		Scene scene = scenes.get(key);
		if (scene == null) {
			throw new IllegalArgumentException("Scene not found: " + key.getSimpleName());
		}
		return scene;
	}

	public Scene getCurrentScene() {
		return currentScene;
	}

	public void setCurrentScene(Class<?> key) {
		setCurrentScene(getScene(key));
	}

	public void setCurrentScene(Scene scene) {
		if (scene == null) {
			throw new IllegalArgumentException("不能设置当前Scene为null.");
		}
		if (this.currentScene != null) {
			this.currentScene.disable();
		}
		this.currentScene = scene;
		this.currentScene.enable();
		this.currentScene.resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
	}

	public Scene getLaunchScene() {
		return launchScene;
	}

	public void setLaunchScene(Class<? extends Scene> key) {
		setLaunchScene(getScene(key));
	}

	public void setLaunchScene(Scene scene) {
		if (scene == null) {
			throw new IllegalArgumentException("Launch scene cannot be null.");
		}
		this.launchScene = scene;
		if (!scene.isInitialized()) {
			setCurrentScene(launchScene);
		}
	}

	@Override
	public void start() {
		scenes.values().forEach(Scene::start);
	}

	@Override
	public void fixedUpdate(float fixedDelta) {
		if (isEnable() && currentScene != null) {
			currentScene.fixedUpdate(fixedDelta);
		}
	}

	@Override
	public void update(float delta) {
		if (isEnable() && currentScene != null) {
			currentScene.update(delta);
		}
	}

	@Override
	public void destroy() {
		scenes.values().forEach(Scene::destroy);
		scenes.clear();
	}

	public void enableInput(InputMultiplexer sceneInputMultiplexer) {
		inputMultiplexer.addProcessor(sceneInputMultiplexer);
	}

	public void disableInput(InputMultiplexer sceneInputMultiplexer) {
		inputMultiplexer.removeProcessor(sceneInputMultiplexer);
	}
}

